package org.example.business.endpoint.http.event.message;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Data
public class HttpReq {

    private Map<DataType, Map<String, HttpData>> dataMap = new HashMap<>();

    public void setPath(String path){
        addHttpData(DataType.PATH, DataType.PATH.name(), path);

    }

    public String getPath(){
        return getHttpData(DataType.PATH, DataType.PATH.name(), "");

    }

    public void setMethod(String method){
        addHttpData(DataType.METHOD, DataType.METHOD.name(), method);

    }

    public String getMethod(){
        return getHttpData(DataType.METHOD, DataType.METHOD.name(), "");

    }

    public void setVersion(String version){
        addHttpData(DataType.VERSION, DataType.VERSION.name(), version);

    }

    public String getVersion(){
        return getHttpData(DataType.VERSION, DataType.VERSION.name(), "");

    }

    public void addHeader(String key, String value){
        getHttpDataMap(DataType.HEADER).put(key, new HttpData(key, value));

    }

    public void putHeaders(Map<String, String> headers){
        headers.forEach((key, value)->{
            getHttpDataMap(DataType.HEADER).put(key, new HttpData(key, value));

        });

    }

    public String getHeader(String key){
        return getHttpData(DataType.HEADER, key, "");

    }

    public void addParam(String key, String value){
        getHttpDataMap(DataType.PARAM).put(key, new HttpData(key, value));

    }

    public void putParam(Map<String, String> params){
        params.forEach((key, value)->{
            getHttpDataMap(DataType.PARAM).put(key, new HttpData(key, value));

        });

    }

    public String getParam(String key){
        return getHttpData(DataType.PARAM, key, "");

    }

    public String toString(){

        StringBuilder builder = new StringBuilder();

        builder.append("HttpReq(");

        builder.append("path: ").append(getPath());
        builder.append(", method: ").append(getMethod());
        builder.append(", version: ").append(getVersion());

        builder.append(")");

        return builder.toString();

    }

    private <T> void addHttpData(DataType type, String key, T value){
        getHttpDataMap(type).put(key, new HttpData(key, value));

    }

    private <T> T getHttpData(DataType type, String key, T fallback){

        HttpData<T> httpData = getHttpDataMap(type).get(key);

        if(null == httpData){
            return fallback;
        }

        return httpData.getData();

    }

    private Map<String, HttpData> getHttpDataMap(DataType type){

        Map<String, HttpData> httpDataMap = dataMap.get(type);

        if(null == httpDataMap){
            httpDataMap = new ConcurrentHashMap<>();
            dataMap.put(type, httpDataMap);

        }

        return httpDataMap;

    }

}
